/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.datamining.api;

import com.algo.clustering.kmeans.AlgoKMeans;
import com.algo.clustering.kmeans.Cluster;
import com.algo.frequentpatterns.apriori_optimized.Itemset;
import com.datamining.gui.FieldChooserUI;
import com.util.openBdf.DpfHandler;
import com.util.opencsv.CSVReader;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.linuxense.javadbf.DBFReader;
import java.io.InputStream;
import java.io.FileInputStream;

/**
 *
 * @author Challiz
 */
public class Facad {

    public static ArrayList products = new ArrayList();
    public static ArrayList data = new ArrayList();
    public static String kmean_out = "";
    public static String apriori_out = "";
    //from eclipse
    public static DBFReader readerdbf;
    static String[] attributesValue;
    public static int id_index;
    public static int product_index;
    public static String[] fieldsNames;

    public static String[] getTableHeader() {
        return fieldsNames;
    }

    public static void showFieldChooser(){
        FieldChooserUI fieldChooser=  new FieldChooserUI(null, true);
        fieldChooser.setData(fieldsNames);
        fieldChooser.setVisible(true);
        /*java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                Facad.fieldChooser.setData(fieldsNames);
                Facad.fieldChooser.setVisible(true);
            }
        });
        while(true){
            if(product_index != 0)
                break;
        }*/
    }

    public void setFile(File file){
        try{
        InputStream inputStream  = new FileInputStream(file);
        readerdbf = new DBFReader(inputStream);
        inputStream.close();
        }

        catch(IOException e) {
            System.out.println( e.getMessage());
            }
    }

    public boolean readDataSet(String fileName) {
        if (fileName.contains(".DBF") || fileName.contains(".dbf")) {
            return readDpfDataSet(fileName);
        } else {
            return readCSVDataSet(fileName);
        }
    }

    public boolean readDpfDataSet(String fileName) {
        products = new ArrayList();
        DpfHandler reader;
        BufferedWriter bw;
        try {
            File file = new File("data.stana");
            // if file doesnt exists, then create it
            if (!file.exists()) {
                file.createNewFile();
            }
            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            bw = new BufferedWriter(fw);

            //read the data
            reader = new DpfHandler(fileName);
            fieldsNames = reader.getFieldsName();
            showFieldChooser();
            int lineNumber = 0;
            int old_id = -1;
            String output = "";
            List<Object> nextLine;
            while ((nextLine = reader.readNext()) != null){
                if (nextLine.size() > 2) {
                    int id = Integer.parseInt(nextLine.get(id_index).toString());
                    if (old_id != id && old_id != -1) {
                        output += "\n";
                    }
                    List<String> record = new ArrayList<String>();
                    for( int i=0; i<nextLine.size(); i++)
                        record.add(nextLine.get(i).toString());
                    data.add(record);
                    String product = nextLine.get(product_index).toString();
                    if (products.indexOf(product) == -1) {
                        products.add(product);
                    }
                    int proId = products.indexOf(product);
                    output += proId + " ";
                    lineNumber++;
                    old_id = id;
                }
            }
            bw.write(output);
            bw.close();

            String output1 = "";
            File file1 = new File("kmeans.stana");
            // if file doesnt exists, then create it
            if (!file1.exists()) {
                file1.createNewFile();
            }
            FileWriter fw1 = new FileWriter(file1.getAbsoluteFile());
            BufferedWriter bw1 = new BufferedWriter(fw1);
            String[] lines = output.split("\n");
            for (int i = 0; i < lines.length; i++) {
                String line = " " + lines[i] + " ";
                for (int p = 0; p < products.size(); p++) {
                    if (line.indexOf(" " + p + " ") == -1) {
                        output1 += "0 ";
                    } else {
                        output1 += "1 ";
                    }
                }
                output1 += "\n";
            }
            bw1.write(output1);
            bw1.close();

            return true;
        } catch (IOException ex) {
            return false;
        }
    }

    public boolean readCSVDataSet(String fileName) {
        products = new ArrayList();
        CSVReader reader;
        BufferedWriter bw;
        try {
            File file = new File("data.stana");
            // if file doesnt exists, then create it
            if (!file.exists()) {
                file.createNewFile();
            }
            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            bw = new BufferedWriter(fw);

            //read the data
            reader = new CSVReader(new FileReader(fileName));
            fieldsNames = reader.getFieldsName();
            showFieldChooser();
            Object[] nextLine;
            int lineNumber = 0;
            int old_id = -1;
            String output = "";
            while ((nextLine = reader.readNext()) != null) {
                if (nextLine.length > 3) {
                    int id = Integer.parseInt(nextLine[id_index].toString());
                    if (old_id != id && old_id != -1) {
                        output += "\n";
                    }

                    List<String> record = new ArrayList<String>();
                    for( int i=0; i<nextLine.length; i++)
                        record.add(nextLine[i].toString());

                    data.add(record);
                    String product = nextLine[product_index].toString();
                    if (products.indexOf(product) == -1) {
                        products.add(product);
                    }
                    int proId = products.indexOf(product);
                    output += proId + " ";
                    lineNumber++;
                    old_id = id;
                }
            }
            bw.write(output);
            bw.close();

            String output1 = "";
            File file1 = new File("kmeans.stana");
            // if file doesnt exists, then create it
            if (!file1.exists()) {
                file1.createNewFile();
            }
            FileWriter fw1 = new FileWriter(file1.getAbsoluteFile());
            BufferedWriter bw1 = new BufferedWriter(fw1);
            String[] lines = output.split("\n");
            for (int i = 0; i < lines.length; i++) {
                String line = " " + lines[i] + " ";
                for (int p = 0; p < products.size(); p++) {
                    if (line.indexOf(" " + p + " ") == -1) {
                        output1 += "0 ";
                    } else {
                        output1 += "1 ";
                    }
                }
                output1 += "\n";
            }
            bw1.write(output1);
            bw1.close();

            return true;
        } catch (IOException ex) {
            return false;
        }
    }

    //k: number of clusters
    public List<Cluster> applyKmeans(int k) {
        try {
            AlgoKMeans algoKMeans = new AlgoKMeans();
            List<Cluster> res = algoKMeans.runAlgorithm("kmeans.stana", k);
            algoKMeans.printStatistics();
            kmean_out = algoKMeans.saveToFile("outputFile");
            return res;
        } catch (NumberFormatException ex) {
            return new ArrayList<Cluster>();
        } catch (IOException ex) {
            return new ArrayList<Cluster>();
        }
    }

    //minsup: Min Support
    //private static ArrayList<Itemset> apriori =
    public ArrayList<Itemset> applyApriori(double minsup) {
        try {
            com.algo.frequentpatterns.apriori_optimized.AlgoApriori_saveToFile apriori = new com.algo.frequentpatterns.apriori_optimized.AlgoApriori_saveToFile();
            ArrayList<Itemset> res = apriori.runAlgorithm(minsup, "data.stana", "output.apr");
            apriori.printStats();
            return res;
        } catch (IOException ex) {
            return new ArrayList<Itemset>();
        }
    }

    public String getAprioriReport() {
        BufferedReader fr = null;
        try {
            String line = "";
            String txt = "";
            fr = new BufferedReader(new FileReader("output.apr"));
            while ((line = fr.readLine()) != null) {
                txt += (line) + "\n";
            }
            fr.close();
            return "\nApriori Report:\n==========================\n" + txt;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Facad.class.getName()).log(Level.SEVERE, null, ex);
            return "\nApriori Report:\n==========================\n";
        } finally {
            try {
                fr.close();
                return "\nApriori Report:\n==========================\n";
            } catch (IOException ex) {
                Logger.getLogger(Facad.class.getName()).log(Level.SEVERE, null, ex);
                return "\nApriori Report:\n==========================\n";
            }
        }
    }

    public String getKmeansReport() {
        return "\nK-means Report:\n==========================\n" + kmean_out;
    }

    public ArrayList<ArrayList<String>> getDataSet() {
        return data;
    }
}
